package com.ruoyi.utils;

import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.entity.LoginVo;
import io.jsonwebtoken.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * 纯JWT Token工具类（不依赖Redis）
 */
@Component
public class JwtTokenUtils {
    private static final Logger log = LoggerFactory.getLogger(JwtTokenUtils.class);
    // Token过期时间：毫秒级
//    private static final long EXPIRE_MILLIS = expireTime * 60 * 1000L;

    // 从若依配置文件读取（与默认TokenService共用配置）
    @Value("${webToken.secret}")
    private String secret; // JWT签名秘钥
    @Value("${webToken.expireTime}")
    private int expireTime; // 过期时间（分钟）
    @Value("${webToken.header}")
    private String tokenPrefix; // Token前缀（Bearer）

    private long getExpireMillis() {
        return expireTime * 60 * 1000L;
    }

    /**
     * 生成纯JWT Token（嵌入用户核心信息）
     */
    public String createToken(LoginVo loginUser) {
        Map<String, Object> claims = new HashMap<>();
        claims.put(Constants.LOGIN_USER_KEY, String.valueOf(loginUser.getUserId()));
        claims.put("nickName", loginUser.getNickName());
        claims.put("exp", new Date(System.currentTimeMillis() + expireTime * 60 * 1000L)); // 使用配置的过期时间
        claims.put("iat", new Date());

        return Jwts.builder()
                .setClaims(claims)
                .signWith(SignatureAlgorithm.HS512, secret)
                .compact();
    }

    /**
     * 解析JWT Token，获取用户信息
     */
    public LoginVo parseToken(String token) {
        if (StringUtils.isEmpty(token)) {
            log.error("JWT Token为空");
            return null;
        }

        try {
            // 1. 去除Token前缀（若前端传入Bearer + Token）
            if (token.startsWith(tokenPrefix)) {
                token = token.replace(tokenPrefix, "").trim();
            }

            // 2. 解析JWT
            Claims claims = Jwts.parser()
                    .setSigningKey(secret)
                    .parseClaimsJws(token)
                    .getBody();

            // 3. 验证过期时间
            Date expireDate = claims.getExpiration();
            if (expireDate.before(new Date())) {
                log.error("JWT Token已过期");
                return null;
            }

            // 4. 构建若依LoginUser对象（适配框架Security上下文）
            LoginVo loginUser = new LoginVo();
            loginUser.setUserId(Long.valueOf(claims.get(Constants.LOGIN_USER_KEY).toString())); // 转换回 Long
            loginUser.setNickName(claims.get("nickName").toString());

            // （可选）如需完整用户信息，可通过用户ID查询数据库（trade-off：牺牲性能换无状态）
            // SysUser user = sysUserMapper.selectById(loginUser.getUserId());
            // loginUser.setUser(user);

            return loginUser;
        } catch (ExpiredJwtException e) {
            log.error("JWT Token过期：{}", e.getMessage());
        } catch (UnsupportedJwtException e) {
            log.error("JWT Token格式不支持：{}", e.getMessage());
        } catch (Exception e) {
            log.error("JWT解析异常：{}", e.getMessage());
        }
        return null;
    }

    /**
     * 验证Token有效性
     */
    public boolean validateToken(String token) {
        return parseToken(token) != null;
    }
}
